package com.ty.filter;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.jwt.JWTUtil;
import cn.hutool.jwt.JWTValidator;
import cn.hutool.jwt.signers.JWTSignerUtil;
import cn.smart.core.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import javax.annotation.PostConstruct;
import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
@Slf4j
public class TokenFilter implements GlobalFilter {

    @Value("${cn.smart.tokenx.key}")
    private String jwtKey;
    private static List<String> WHITE_LIST = CollUtil.newArrayList("/api/user/login", "/api/user/register");

    @PostConstruct
    public void test(){


        Map<String, Object> map1 = new HashMap<String, Object>();
        map1.put("id", 1);
        map1.put("tel","132554566"); //脱敏  13243341212   ->  132****1212
        map1.put("exp", System.currentTimeMillis()/1000 +   60 * 60 * 24 * 15); //过期时间 60 * 60 * 24 * 15
        String accessToken = JWTUtil.createToken(map1, jwtKey.getBytes());
    }


    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        URI uri = request.getURI();
        String path = uri.getPath();
        //如果路径在白名单中，则放行
        if(WHITE_LIST.contains(path)){
            // 接着往下走
            return chain.filter(exchange);
        }
        String token = request.getHeaders().getFirst("token");
        if(ObjectUtil.isEmpty(token)){
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            response.setComplete();
        }
        //有token
        //开始验证token
        boolean b = false;
        try {
            JWTValidator.of(token)
                    .validateAlgorithm(JWTSignerUtil.hs256(jwtKey.getBytes())) // 验证第3部分的签名是否正确
                    .validateDate(DateUtil.date()); //验证是否过期
            b=true;
        } catch (ValidateException ex){
            ex.printStackTrace();
            BizException.throwException(406,"token过期");
        }
        catch (Exception ex){
            ex.printStackTrace();
        }
        if(b==false){
            //验证不通过
            BizException.throwException(403,"token不正确或失效");
        }

        return chain.filter(exchange);
    }
}